#pragma once

#ifdef WIN32
#	define WIN32_LEAN_AND_MEAN // avoid including unnecessary WIN32 header files
#	include <windows.h>
#	define ModuleHandle HMODULE // DLL handle
#   define INVALID_MODULE_HANDLE 0
#   define MODULE_SUFFIX ".dll"
#   define DELIMETER '\\'
#else
#   include <stdio.h>  
#   include <string.h> 
#   include <stdlib.h>  
#   include <dirent.h>  
#   include <sys/stat.h>  
#   include <unistd.h>  
#   include <sys/types.h>
#   include <dlfcn.h>
#	define ModuleHandle void* // LINUX SO handle
#   define INVALID_MODULE_HANDLE nullptr
#   define MODULE_SUFFIX ".so"
#   define DELIMETER '/'
#endif // WIN32

#include <cstdint>
#include "service.hh"

#ifdef WIN32
#	define FuncExport extern "C" __declspec(dllexport) // WIN32 DLL exporter
#else
#	define FuncExport extern "C" // LINUX shared object exporter
#endif // WIN32

// Module type
enum class ModuleType : std::uint32_t {
    NONE = 0,
    EVENT_MODULE = 1, // Receive engine event
    SERVICE_MODULE, // The module ONLY expose service API
};

inline bool isKratosModule(ModuleType moduleType) {
    switch (moduleType) {
        case ModuleType::EVENT_MODULE:
        case ModuleType::SERVICE_MODULE:
            return true;
        default:
            break;
    }
    return false;
}

namespace kratos { namespace engine {
    class Service;
}};

using ModuleExportFunc = kratos::engine::Service*(*)();
using UninstallExportFunc = void(*)();
using ModuleTypeExportFunc = ModuleType(*)();
#define ModuleExportFuncName "getService"
#define UninstallExportFuncName "uninstallService"
#define ModuleTypeExportFuncName "getType"
